package com.gzhryc.weixin.api.resource;

import com.gzhryc.common.json.JsonTools;
import com.gzhryc.weixin.gzh.AbsWeixinApi;
import com.gzhryc.weixin.api.DefaultApiResponse;
import com.gzhryc.weixin.gzh.models.AccessToken;
import com.gzhryc.weixin.api.resource.enums.ResourceTypeEnum;
import com.gzhryc.weixin.api.resource.msg.req.AddNewsRequest;
import com.gzhryc.weixin.api.resource.msg.req.GetResourceListRequest;
import com.gzhryc.weixin.api.resource.msg.req.UpdateNewsRequest;
import com.gzhryc.weixin.api.resource.msg.resp.*;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class WxResourceApi extends AbsWeixinApi{
	
	private Logger log = Logger.getLogger(WxResourceApi.class);

	public WxResourceApi(AccessToken accessToken) {
		super(accessToken);
	}

	/**
	 * 获取永久资源数量
	 * @return
	 */
	public ResourceCountResponse countResource(){
		CloseableHttpResponse response = null;
		try {
			CloseableHttpClient httpclient = HttpClients.createDefault();
			URI uri = new URIBuilder()
		        .setScheme("https")
		        .setHost("api.weixin.qq.com")
		        .setPath("/cgi-bin/material/get_materialcount")
		        .setParameter("access_token",accessToken.getAccess_token())
		        .build();
			HttpGet httpget = new HttpGet(uri);
			response = httpclient.execute(httpget);
			HttpEntity entity = response.getEntity();
			if(entity != null){
				String str = EntityUtils.toString(entity);
				if(DefaultApiResponse.is(str)){
					accessToken.queuePut(JsonTools.fromJson(str, DefaultApiResponse.class));
				}else{
					return JsonTools.fromJson(str, ResourceCountResponse.class);
				}
			}
		} catch(Exception e){
			log.error("countResource error", e);
		} finally {
			if(response != null){
				try {
					response.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}

	//=== 图文资源 ===//
	
	/**
	 * 获取多个微信图文资源
	 * @param offset
	 * @param count
	 * @return
	 */
	public GetNewsListResponse getNewsResourceList(Integer offset,Integer count){
		CloseableHttpResponse response = null;
		try {
			if(accessToken != null){
				CloseableHttpClient httpclient = HttpClients.createDefault();
				
				URI uri = new URIBuilder()
			        .setScheme("https")
			        .setHost("api.weixin.qq.com")
			        .setPath("/cgi-bin/material/batchget_material")
			        .setParameter("access_token",accessToken.getAccess_token())
			        .build();
				
				GetResourceListRequest request = new GetResourceListRequest();
				request.type = ResourceTypeEnum.news.name();
				request.offset = offset;
				request.count = count;
			
				StringEntity strEntity = new StringEntity(JsonTools.toJson(request),
				        ContentType.create("application/json", Consts.UTF_8));

				HttpPost httppost = new HttpPost(uri);
				httppost.setEntity(strEntity);
				
				response = httpclient.execute(httppost);
				HttpEntity entity = response.getEntity();
				if(entity != null){
					String str = EntityUtils.toString(entity,Charset.forName("UTF-8"));
					if(DefaultApiResponse.is(str)){
						accessToken.queuePut(JsonTools.fromJson(str, DefaultApiResponse.class));
					}else{
						return JsonTools.fromJson(str, GetNewsListResponse.class);
					}
				}
			}
		} catch(Exception e){
			e.printStackTrace();
		} finally {
			if(response != null){
				try {
					response.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
	
	/**
	 * 获取单个微信图文资源
	 * @param mediaId
	 * @return
	 */
	public GetNewsResponse getNewsResource(String mediaId){
		CloseableHttpResponse response = null;
		try {
			if(accessToken != null){
				CloseableHttpClient httpclient = HttpClients.createDefault();
				
				URI uri = new URIBuilder()
			        .setScheme("https")
			        .setHost("api.weixin.qq.com")
			        .setPath("/cgi-bin/material/get_material")
			        .setParameter("access_token",accessToken.getAccess_token())
			        .build();
				
				Map<String,Object> request = new HashMap<String,Object>();
				request.put("media_id", mediaId);
				StringEntity strEntity = new StringEntity(JsonTools.toJson(request),
				        ContentType.create("application/json", Consts.UTF_8));

				HttpPost httppost = new HttpPost(uri);
				httppost.setEntity(strEntity);
				
				response = httpclient.execute(httppost);
				HttpEntity entity = response.getEntity();
				if(entity != null){
					String str = EntityUtils.toString(entity,Charset.forName("UTF-8"));
					if(DefaultApiResponse.is(str)){
						accessToken.queuePut(JsonTools.fromJson(str, DefaultApiResponse.class));
					}else{
						return JsonTools.fromJson(str, GetNewsResponse.class);
					}
				}
			}
		} catch(Exception e){
			e.printStackTrace();
		} finally {
			if(response != null){
				try {
					response.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
	
	/**
	 * 新增图文资源
	 * @param request
	 * @return
	 */
	public AddNewsResponse addNews(AddNewsRequest request){
		CloseableHttpResponse response = null;
		try {
			CloseableHttpClient httpclient = HttpClients.createDefault();

			URI uri = new URIBuilder()
		        .setScheme("https")
		        .setHost("api.weixin.qq.com")
		        .setPath("/cgi-bin/material/add_news")
		        .setParameter("access_token",accessToken.getAccess_token())
		        .build();
			
			StringEntity strEntity = new StringEntity(JsonTools.toJson(request),
			        ContentType.create("application/json", Consts.UTF_8));
			
			HttpPost httppost = new HttpPost(uri);
			httppost.setEntity(strEntity);
			
			response = httpclient.execute(httppost);
			HttpEntity entity = response.getEntity();
			if(entity != null){
				String str = EntityUtils.toString(entity,Charset.forName("UTF-8"));
				if(DefaultApiResponse.is(str)){
					accessToken.queuePut(JsonTools.fromJson(str,DefaultApiResponse.class));
				}else{
					AddNewsResponse result = JsonTools.fromJson(str,AddNewsResponse.class);
					return result;
				}
				
			}
		} catch(Exception e){
			e.printStackTrace();
		} finally {
			if(response != null){
				try {
					response.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		return null;
	}
	
	/**
	 * 上传微信图文资源内容中的图片
	 * @param file
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String uploadNewsContentImg(File file){
		CloseableHttpResponse response = null;
		try {
			CloseableHttpClient httpclient = HttpClients.createDefault();
			
			URI uri = new URIBuilder()
		        .setScheme("https")
		        .setHost("api.weixin.qq.com")
		        .setPath("/cgi-bin/media/uploadimg")
		        .setParameter("access_token",accessToken.getAccess_token())
		        .build();
		
			FileBody bin = new FileBody(file);
			HttpEntity reqEntity = MultipartEntityBuilder.create()
                    .addPart("media", bin)
                    .build();
			
			HttpPost httppost = new HttpPost(uri.toString());
			httppost.setEntity(reqEntity);
			
			response = httpclient.execute(httppost);
			HttpEntity entity = response.getEntity();
			if(entity != null){
				String str = EntityUtils.toString(entity,Charset.forName("UTF-8"));
				Map<String,Object> result = JsonTools.fromJson(str, Map.class);
				if(result.containsKey("url")){
					return result.get("url").toString();
				}else{
					accessToken.queuePut(JsonTools.fromJson(str,DefaultApiResponse.class));
				}
			}
		} catch(Exception e){
			e.printStackTrace();
		} finally {
			if(response != null){
				try {
					response.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
	
	/**
	 * 修改微信图文资源
	 * @param request
	 * @return
	 */
	public boolean updateNews(UpdateNewsRequest request){
		CloseableHttpResponse response = null;
		try {
			CloseableHttpClient httpclient = HttpClients.createDefault();

			URI uri = new URIBuilder()
		        .setScheme("https")
		        .setHost("api.weixin.qq.com")
		        .setPath("/cgi-bin/material/update_news")
		        .setParameter("access_token",accessToken.getAccess_token())
		        .build();
			
			StringEntity strEntity = new StringEntity(JsonTools.toJson(request),
			        ContentType.create("application/json", Consts.UTF_8));
			
			HttpPost httppost = new HttpPost(uri);
			httppost.setEntity(strEntity);
			
			response = httpclient.execute(httppost);
			HttpEntity entity = response.getEntity();
			if(entity != null){
				String str = EntityUtils.toString(entity,Charset.forName("UTF-8"));
				DefaultApiResponse result = JsonTools.fromJson(str,DefaultApiResponse.class);
				if(result.getErrcode() == 0){
					return true;
				}else{
					accessToken.queuePut(result);
				}
			}
		} catch(Exception e){
			e.printStackTrace();
		} finally {
			if(response != null){
				try {
					response.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		return false;
	}
	
	/**
	 * 获取非图文资源
	 * @param offset
	 * @param count
	 * @return
	 */
	public GetResourceListResponse getResourceList(String type,Integer offset,Integer count){
		if(ResourceTypeEnum.news.name().equals(type)){
			return null;
		}
		CloseableHttpResponse response = null;
		try {
			if(accessToken != null){
				CloseableHttpClient httpclient = HttpClients.createDefault();
				
				URI uri = new URIBuilder()
			        .setScheme("https")
			        .setHost("api.weixin.qq.com")
			        .setPath("/cgi-bin/material/batchget_material")
			        .setParameter("access_token",accessToken.getAccess_token())
			        .build();
				
				GetResourceListRequest request = new GetResourceListRequest();
				request.type = type;
				request.offset = offset;
				request.count = count;
			
				StringEntity strEntity = new StringEntity(JsonTools.toJson(request),
				        ContentType.create("application/json", Consts.UTF_8));

				HttpPost httppost = new HttpPost(uri);
				httppost.setEntity(strEntity);
				
				response = httpclient.execute(httppost);
				HttpEntity entity = response.getEntity();
				if(entity != null){
					String str = EntityUtils.toString(entity,Charset.forName("UTF-8"));
					if(DefaultApiResponse.is(str)){
						accessToken.queuePut(JsonTools.fromJson(str, DefaultApiResponse.class));
					}else{
						return JsonTools.fromJson(str, GetResourceListResponse.class);
					}
				}
			}
		} catch(Exception e){
			e.printStackTrace();
		} finally {
			if(response != null){
				try {
					response.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
	
	/**
	 * 新增资源
	 * @param file
	 * @return
	 */
	public AddResourceResponse AddResource(File file){
		CloseableHttpResponse response = null;
		try {
			if(accessToken != null){
				CloseableHttpClient httpclient = HttpClients.createDefault();
				
				URI uri = new URIBuilder()
			        .setScheme("https")
			        .setHost("api.weixin.qq.com")
			        .setPath("/cgi-bin/material/add_material")
			        .setParameter("access_token",accessToken.getAccess_token())
			        .build();
				
				FileBody bin = new FileBody(file);
				HttpEntity reqEntity = MultipartEntityBuilder.create()
	                    .addPart("media", bin)
	                    .build();

				HttpPost httppost = new HttpPost(uri.toString());
				httppost.setEntity(reqEntity);
				
				response = httpclient.execute(httppost);
				HttpEntity entity = response.getEntity();
				if(entity != null){
					String str = EntityUtils.toString(entity,Charset.forName("UTF-8"));
					if(DefaultApiResponse.is(str)){
						accessToken.queuePut(JsonTools.fromJson(str, DefaultApiResponse.class));
					}else{
						return JsonTools.fromJson(str, AddResourceResponse.class);
					}
				}
			}
		} catch(Exception e){
			e.printStackTrace();
		} finally {
			if(response != null){
				try {
					response.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
	
	/**
	 * 新增视频资源
	 * @param title			视频资源名称
	 * @param introduction	视频素材的描述
	 * @param file
	 * @return
	 */
	public AddResourceResponse AddVideoResource(String title,String introduction,File file){
		CloseableHttpResponse response = null;
		try {
			if(accessToken != null){
				CloseableHttpClient httpclient = HttpClients.createDefault();
				
				URI uri = new URIBuilder()
			        .setScheme("https")
			        .setHost("api.weixin.qq.com")
			        .setPath("/cgi-bin/material/add_material")
			        .setParameter("access_token",accessToken.getAccess_token())
			        .build();
				
				Map<String,Object> data = new HashMap<String,Object>();
				data.put("title", title);
				data.put("introduction", introduction);
				
				FileBody bin = new FileBody(file);
				HttpEntity reqEntity = MultipartEntityBuilder.create()
	                    .addPart("media", bin)
	                    .addTextBody("description", JsonTools.toJson(data))
	                    .build();

				HttpPost httppost = new HttpPost(uri.toString());
				httppost.setEntity(reqEntity);
				
				response = httpclient.execute(httppost);
				HttpEntity entity = response.getEntity();
				if(entity != null){
					String str = EntityUtils.toString(entity,Charset.forName("UTF-8"));
					if(DefaultApiResponse.is(str)){
						accessToken.queuePut(JsonTools.fromJson(str, DefaultApiResponse.class));
					}else{
						return JsonTools.fromJson(str, AddResourceResponse.class);
					}
				}
			}
		} catch(Exception e){
			e.printStackTrace();
		} finally {
			if(response != null){
				try {
					response.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
	
	/**
	 * 删除资源
	 * @param mediaId
	 * @return
	 */
	public boolean deleteResource(String mediaId){
		CloseableHttpResponse response = null;
		try {
			CloseableHttpClient httpclient = HttpClients.createDefault();

			URI uri = new URIBuilder()
		        .setScheme("https")
		        .setHost("api.weixin.qq.com")
		        .setPath("/cgi-bin/material/del_material")
		        .setParameter("access_token",accessToken.getAccess_token())
		        .build();
			
			Map<String,Object> request = new HashMap<String,Object>();
			request.put("media_id", mediaId);
			StringEntity strEntity = new StringEntity(JsonTools.toJson(request),
			        ContentType.create("application/json", Consts.UTF_8));
			
			HttpPost httppost = new HttpPost(uri);
			httppost.setEntity(strEntity);
			
			response = httpclient.execute(httppost);
			HttpEntity entity = response.getEntity();
			if(entity != null){
				String str = EntityUtils.toString(entity,Charset.forName("UTF-8"));
				DefaultApiResponse result = JsonTools.fromJson(str,DefaultApiResponse.class);
				if(result.getErrcode() == 0){
					return true;
				}else{
					accessToken.queuePut(result);
				}
			}
		} catch(Exception e){
			e.printStackTrace();
		} finally {
			if(response != null){
				try {
					response.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		return false;
	}
	
	/**
	 * 获取所有消息模板
	 * @return
	 */
	public GetMsgTemplateResponse getMsgTemplate(){
		CloseableHttpResponse response = null;
		try {
			if(accessToken != null){
				CloseableHttpClient httpclient = HttpClients.createDefault();
				
				URI uri = new URIBuilder()
			        .setScheme("https")
			        .setHost("api.weixin.qq.com")
			        .setPath("/cgi-bin/template/get_all_private_template")
			        .setParameter("access_token",accessToken.getAccess_token())
			        .build();
				
				HttpGet httpget = new HttpGet(uri);
				response = httpclient.execute(httpget);

				HttpEntity entity = response.getEntity();
				if(entity != null){
					String str = EntityUtils.toString(entity,Charset.forName("UTF-8"));
					if(DefaultApiResponse.is(str)){
						accessToken.queuePut(JsonTools.fromJson(str, DefaultApiResponse.class));
					}else{
						return JsonTools.fromJson(str, GetMsgTemplateResponse.class);
					}
				}
			}
		} catch(Exception e){
			e.printStackTrace();
		} finally {
			if(response != null){
				try {
					response.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
	
	/**
	 * 上传临时资源
	 * @param path 资源路径
	 * @param format 资源类型
	 * @return
	 */
	public TemporaryResourceUploadResponse temporaryUpload(String path,String format){
		try {
			URI uri = new URIBuilder()
		        .setScheme("https")
		        .setHost("api.weixin.qq.com")
		        .setPath("/cgi-bin/media/upload")
		        .setParameter("access_token",accessToken.getAccess_token())
		        .setParameter("type",format)
		        .build();
			
			log.debug("上传文件：" + path);
			
			Process process = Runtime.getRuntime().exec("curl -F media=@"+path+" "+uri.toString());
			
			int i = 0;
			byte[] buffer = new byte[1024];
			
			InputStream in = process.getInputStream();
			StringBuffer str = new StringBuffer();
			while((i = in.read(buffer)) > 0){
				str.append(new String(buffer,0,i));
			}
			
			if(str.length() > 0){
				String reuslt = str.toString();
				if(isError(reuslt)){
					accessToken.queuePut(JsonTools.fromJson(reuslt, DefaultApiResponse.class));
				}else{
					return JsonTools.fromJson(reuslt, TemporaryResourceUploadResponse.class);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (URISyntaxException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 下载临时资源
	 * @param mediaId
	 * @param path
	 */
	public String temporaryDownload(String mediaId,String path){
		CloseableHttpResponse response = null;
		try {
			URI uri = new URIBuilder()
		        .setScheme("https")
		        .setHost("api.weixin.qq.com")
		        .setPath("/cgi-bin/media/get")
		        .setParameter("access_token",accessToken.getAccess_token())
		        .setParameter("media_id",mediaId)
		        .build();
			
			CloseableHttpClient httpclient = HttpClients.createDefault();
			
			HttpGet httpget = new HttpGet(uri);
			response = httpclient.execute(httpget);
			
			HttpEntity entity = response.getEntity();
			
			if(entity != null){
				InputStream in = entity.getContent();
				if(entity.getContentType().getValue().contains("application/json")){
					int i = 0;
					byte[] buffer = new byte[1024];
					StringBuffer str = new StringBuffer();
					while((i = in.read(buffer)) > 0){
						str.append(new String(buffer,0,i));
					}
					if(str.length() > 0){
						String reuslt = str.toString();
						if(isError(reuslt)){
							accessToken.queuePut(JsonTools.fromJson(reuslt, DefaultApiResponse.class));
						}
					}
				}else{
					if(StringUtils.isBlank(FilenameUtils.getExtension(path))){
						Header header = response.getFirstHeader("Content-Disposition");
						if(header != null){
							String disposition = header.getValue();
							Pattern pat = Pattern.compile("filename=\"(.*)\"");
							Matcher mat = pat.matcher(disposition);
							if(mat.find()){
								path = path + mat.group(1);
							}
						}
					}
					log.debug("保存路径："+path);
					File file = new File(path);
					if(!file.exists()){
						file.getParentFile().mkdirs();
						file.createNewFile();
					}
					FileOutputStream out = new FileOutputStream(file);
					int i = 0;
					byte[] buffer = new byte[1024];

					while((i = in.read(buffer)) > 0){
						out.write(buffer, 0, i);
					}
					out.close();
					in.close();
					return path;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (URISyntaxException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}  finally {
			if(response != null){
				try {
					response.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		return null;
	}

}
